import 'dart:math';

import 'package:ceramics/model/ab_singleton.dart';
import 'package:ceramics/util/ab_api.dart';
import 'package:ceramics/util/ab_init_db.dart';
import 'package:ceramics/util/ab_oss_fetch_util.dart';
import 'package:ceramics/util/ab_value_converter.dart';

import 'ab_oauth.dart';

class ABComment {
  int? id;
  int type;
  String value;
  String nickname;
  String avatar;
  OSSResponse? avatarOss;
  String userId;
  int? worksId;
  int? videoId;

  ABComment({
    this.id,
    required this.type,
    required this.value,
    required this.nickname,
    required this.avatar,
    required this.userId,
    this.worksId,
    this.videoId
  });

  static ABComment myComment(int type, String value, {int? worksId, int? videoId}) {
    return ABComment(
      type: type,
      value: value,
      nickname: ABSingleton.user?.nickname ?? '',
      avatar: ABSingleton.user?.avatar ?? '',
      userId: ABSingleton.user?.userId ?? '',
      worksId: worksId,
      videoId: videoId
    );
  }

  static ABComment fromJson(Map<String, dynamic> json) {
    return ABComment(
      id: valueToInt(json['id']),
      type: valueToInt(json['type']),
      value: valueToString(json['value']),
      nickname: valueToString(json['nickname']),
      avatar: valueToString(json['avatar']),
      userId: valueToString(json['userId']),
      worksId: valueToInt(json['worksId']),
      videoId: valueToInt(json['videoId']),
    )..avatarOss = json['avatar_oss'];
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'type': type,
      'value': value,
      'nickname': nickname,
      'avatar': avatar,
      'userId': userId,
      'worksId': worksId,
      'videoId': videoId
    };
  }

  static Future<List<ABComment>> queryForWorks(int worksId) async {
    var list = await abDB.query('comments', where: 'worksId = ?', whereArgs: [worksId], orderBy: 'id DESC');
    list = await list.replaceOSSURL({'avatar':'image'});
    return list.map((e) => ABComment.fromJson(e)).toList();
  }

  static Future<List<ABComment>> queryForVideo(int videoId) async {
    var list = await abDB.query('comments', where: 'videoId = ?', whereArgs: [videoId], orderBy: 'id DESC');
    list = await list.replaceOSSURL({'avatar':'image'});
    return list.map((e) => ABComment.fromJson(e)).toList();
  }

  static Future<int> countForVideo(int videoId) async {
    var result = await abDB.query('comments', where: 'videoId = ?', whereArgs: [videoId]);
    return result.length;
  }

  save() async {
    await Future.delayed(const Duration(milliseconds: 500));
    if (id == null) {
      id = await abDB.insert('comments', toJson());
    } else {
      abDB.update('comments', toJson(), where: 'id = ?', whereArgs: [id]);
    }
  }

  static deleteCommentsWithUserId(String s) {
    abDB.delete('comments', where: 'userId = ?', whereArgs: [s]);
  }

  static replaceUsers(List<ABUser> users) async {
    var works = await abDB.query('comments');
    for (var work in works) {
      var userId = work['userId'];
      if (users.isEmpty) {
        break;
      }
      var randomIdx = Random().nextInt(users.length);
      var randomUser = users[randomIdx];
      await abDB.update('comments', {'userId': randomUser.userId, 'nickname': randomUser.nickname, 'avatar': randomUser.avatar}, where: 'userId = ?', whereArgs: [userId]);
      users.removeWhere((element) => element.userId == randomUser.userId);
    }
  }
}